// 源自Inferno utils/6l/l.h和相关文件。
// https:
// None
// None
// None
// None
// None
// None
// None
// None
// None
// None
// 特此向任何获得副本的人免费授予许可
// 本软件和相关文档文件（“软件”）的
// 在软件中不受限制，包括但不限于权利
// 使用、复制、修改、合并、发布、分发、再许可和/或销售
// 软件的副本，并允许向其提供软件的人员
// 按照以下条件提供：
// None
// 上述版权声明和本许可声明应包含在
// 软件的所有副本或主要部分。
// None
// 本软件按“原样”提供，无任何形式的明示或明示担保
// 默示，包括但不限于适销性保证，
// 适用于特定目的和非侵权。在任何情况下
// 作者或版权持有人应承担任何索赔、损害或其他责任
// 无论是在合同诉讼、侵权诉讼或其他诉讼中，由以下原因引起的责任：，
// 与本软件有关或与本软件的使用或其他交易有关
// 软件。

package sym

// 符号种类描述由符号表示的内存种类。
type SymKind uint8

// 定义的符号种类值。
// None
// TODO（rsc）：给出惯用的Go名称。
// go:生成梯边梁-类型=符号种类
const (
	Sxxx SymKind = iota
	STEXT
	SELFRXSECT
	SMACHOPLT

	// 只读部分。
	STYPE
	SSTRING
	SGOSTRING
	SGOFUNC
	SGCBITS
	SRODATA
	SFUNCTAB

	SELFROSECT

	// 带有重新定位的只读节。
	// None
	// 默认情况下，上面的类型STYPE-SFUNCTAB会写入.rodata部分。
	// 链接共享对象时，某些概念上的“只读”类型需要
	// 通过重新定位并将其放入名为
	// “.rodata”与系统链接器的交互较差。GNU链接器
	// 通过安排名称的各个部分来支持这种情况
	// “data.rel.ro.XXX”将由动态链接器在
	// 重新定位已应用，因此当Go链接器创建共享
	// 对象它检查上述类型的所有对象，并碰撞任何
	// 将其重新定位到下面相应的类型，然后
	// 用适当的魔法名称写在章节中。
	STYPERELRO
	SSTRINGRELRO
	SGOSTRINGRELRO
	SGOFUNCRELRO
	SGCBITSRELRO
	SRODATARELRO
	SFUNCTABRELRO

	// .data.rel.ro的一部分（如果存在），否则为.rodata的一部分。
	STYPELINK
	SITABLINK
	SSYMTAB
	SPCLNTAB

	// 可写部分。
	SFirstWritable
	SBUILDINFO
	SELFSECT
	SMACHO
	SMACHOGOT
	SWINDOWS
	SELFGOT
	SNOPTRDATA
	SINITARR
	SDATA
	SXCOFFTOC
	SBSS
	SNOPTRBSS
	SLIBFUZZER_EXTRA_COUNTER
	STLSBSS
	SXREF
	SMACHOSYMSTR
	SMACHOSYMTAB
	SMACHOINDIRECTPLT
	SMACHOINDIRECTGOT
	SFILEPATH
	SDYNIMPORT
	SHOSTOBJ
	SUNDEFEXT // 外部链接器解析的未定义符号

	// 调试信息部分
	SDWARFSECT
	// 矮人符号类型
	SDWARFCUINFO
	SDWARFCONST
	SDWARFFCN
	SDWARFABSFCN
	SDWARFTYPE
	SDWARFVAR
	SDWARFRANGE
	SDWARFLOC
	SDWARFLINES

	// ABI别名（这些别名永远不会出现在输出中）
	SABIALIAS
)

// AbiSymKindToSymKind映射从对象文件读取的值
// 类型cmd/internal/objabi.SymKind）转换为类型SymKind的值。
var AbiSymKindToSymKind = [...]SymKind{
	Sxxx,
	STEXT,
	SRODATA,
	SNOPTRDATA,
	SDATA,
	SBSS,
	SNOPTRBSS,
	STLSBSS,
	SDWARFCUINFO,
	SDWARFCONST,
	SDWARFFCN,
	SDWARFABSFCN,
	SDWARFTYPE,
	SDWARFVAR,
	SDWARFRANGE,
	SDWARFLOC,
	SDWARFLINES,
	SABIALIAS,
	SLIBFUZZER_EXTRA_COUNTER,
}

// 只读是构成只读部分的符号类型。在某些方面
// 在某些情况下，如果需要重新安置，则会将其转化为
// 使用relROMap重新读取ro部分。
var ReadOnly = []SymKind{
	STYPE,
	SSTRING,
	SGOSTRING,
	SGOFUNC,
	SGCBITS,
	SRODATA,
	SFUNCTAB,
}

// RelROMap描述了只读符号到rel ro的转换
// 符号。
var RelROMap = map[SymKind]SymKind{
	STYPE:     STYPERELRO,
	SSTRING:   SSTRINGRELRO,
	SGOSTRING: SGOSTRINGRELRO,
	SGOFUNC:   SGOFUNCRELRO,
	SGCBITS:   SGCBITSRELRO,
	SRODATA:   SRODATARELRO,
	SFUNCTAB:  SFUNCTABRELRO,
}

// 如果类型是数据类型，IsData返回true。
func (t SymKind) IsData() bool {
	return t == SDATA || t == SNOPTRDATA || t == SBSS || t == SNOPTRBSS
}
